#ifndef __APP_LIHGT_CONTROL_H__
#define __APP_LIHGT_CONTROL_H__

#include "app_common.h"

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */


#define CTRL_HSV_H_MAX 360                                           ///< Control calculate range 0 ~ 360
#define CTRL_CAL_VALUE_RANGE 1000.0                                  ///< Control calculate range 0 ~ 1000
#define CTRL_CW_BRIGHT_VALUE_MAX CTRL_CAL_VALUE_RANGE                ///< Control cw calc max bright value
#define CTRL_CW_BRIGHT_VALUE_MIN (CTRL_CW_BRIGHT_VALUE_MAX * 0.01)   ///< Control cw calc min bright value (max value * 0.01)
#define CTRL_RGB_BRIGHT_VALUE_MAX CTRL_CAL_VALUE_RANGE               ///< Control RGB calc max bright value
#define CTRL_RGB_BRIGHT_VALUE_MAX CTRL_CAL_VALUE_RANGE               ///< Control RGB calc max bright value
#define CTRL_RGB_BRIGHT_VALUE_MIN (CTRL_RGB_BRIGHT_VALUE_MAX * 0.01) ///< Control RGB calc min bright value

#define OUT_CONTROL_MAX_VALUE       0xFFFF

#define FACTORY_DEFAULT_BRIGHT_VALUE        500
#define FACTORY_DEFAULT_TEMPER_VALUE        500
#define DISTRIBUTION_REMINDER_BRIGHT_VALUE  500
#define DISTRIBUTION_REMINDER_TEMPER_VALUE  500

#define CURVE_FORWARD_GAMMA     2.2
#define CURVE_REVERSAL_GAMMA    (1 / 2.2)

/**
 * @note Light control data structure
 * storage the light control data(normal issued by app)
 */
typedef enum
{
    WHITE_MODE = 0,
    COLOR_MODE,
    SCENE_MODE,
    MUSIC_MODE,
    MODE_MAX,
} LIGHT_MODE_E;

typedef enum
{
    SHADE_PARAM_BRIGHT = 0,
    SHADE_PARAM_COLOR,
} SHADE_PARAM_E;

/**
 * @note Light control data structure
 * storage the light control data(normal issued by app)
 */
typedef struct
{
    APP_DATA_T app_data;
    uint32_t off_gradient;
    uint32_t on_gradient;
	SHADE_PARAM_E shade_param;
    UINT8_T nwk_flag;
    UINT16_T count_down_cnt;
    UINT16_T sg_usRemainTime100ms;
    UINT16_T blinkTime100ms;
} LIGHT_CTRL_DATA_T;


/**
 * @note Bright 5ways value structure
 * Used in light gradually change calculation process
 */
typedef struct
{
    USHORT_T red;
    USHORT_T green;
    USHORT_T blue;
    USHORT_T white;
    USHORT_T warm;
} LIGHT_DATA_T;

/**
 * @note: light ctrl blink proc
 * @param {none}
 * @return: UCHAR_T
 */
VOID_T app_light_ctrl_blink_display(LIGHT_DATA_T *data);

/**
 * @note: set light count down cnt
 * @param [in] {ULONG_T}count
 * @return: none
 */
VOID_T app_light_count_down_cnt_set(ULONG_T count);

/**
 * @note: return app_light_count_down_cnt_get
 * @param [in] none
 * @return: app_light_count_down_cnt_get
 */
ULONG_T app_light_count_down_cnt_get(VOID_T);

/**
 * @note: calculate the CW Light_Handle.TargetVal according to
 *          the Light_Data value, and cw output limit and amplify process!
 * @param [in] {USHORT_T Bright -> Light_Data bright }
 * @param [in] {USHORT_T Temper -> Light_Data temperature}
 * @param [out] {LIGHT_DATA_T *Result -> calc result}
 * @return: none
 */
VOID_T app_light_ctrl_data_calc_cw(USHORT_T bright, USHORT_T temper, LIGHT_DATA_T *result);

/**
 * @berief: set light switch data, adapte control data issued by system
 *          to control data format.
 * @param [in] {UINT8_T bONOFF -> switch data, TRUE will turn on}
 * @return: OPERATE_RET -> OPRT_OK meaning need to call app_light_ctrl_proc() function!
 */
OPERATE_RET app_light_ctrl_data_switch_set(UINT8_T on_off);

UINT16_T app_light_ctrl_data_switch_on_gradient(VOID_T);

UINT16_T app_light_ctrl_data_switch_off_gradient(VOID_T);

/**
 * @berief: set light mode data
 * @param [in ]{LIGHT_MODE_E Mode}
 * @attention:Mode value is below:
 *                                  WHITE_MODE = 0,
 *                                  COLOR_MODE = 1,
 *                                  SCENE_MODE = 2,
 *                                  MUSIC_MODE = 3,
 * @return: OPERATE_RET -> OPRT_OK meaning need to call app_light_ctrl_proc() function!
 */
OPERATE_RET app_light_ctrl_data_mode_set(LIGHT_MODE_E mode);

/**
 * @note: get light switch data
 * @param {OUT UINT8_T *onff -> switch data return}
 * @return: OPERATE_RET
 */
USHORT_T app_light_ctrl_handle_data_bright_get(VOID_T);

/**
 * @berief: set light bright data, adapte control data issued by system
 *          to control data format.
 * @param [in] {IN USHORT_T usBright}
 * @attention: acceptable range:10~1000
 * @attention: set bright value, will auto set the Mode to WHITE_MODE !
 * @return: OPERATE_RET -> OPRT_OK meaning need to call app_light_ctrl_proc() function!
 */
OPERATE_RET app_light_ctrl_data_bright_set(USHORT_T bright, USHORT_T transtime);

/**
 * @berief: set light temrperature data, adapte control data issued by system
 *          to control data format.
 * @param [in] {IN USHORT_T usTemperature}
 * @attention: acceptable range:0~1000
 * @return: OPERATE_RET -> OPRT_OK meaning need to call app_light_ctrl_proc() function!
 */
OPERATE_RET app_light_ctrl_data_temp_set(USHORT_T temperature, USHORT_T transtime);

/**
 * @berief: get light switch data
 * @param [out] {OUT UINT8_T *onpONOFFoff -> switch data return}
 * @return: OPERATE_RET
 */
UINT8_T app_light_ctrl_data_switch_get(void);
/**
 * @note: light switch data comparison
 * @param {OUT UINT8_T *onff -> switch data return}
 * @return: OPERATE_RET
 */
OPERATE_RET app_light_ctrl_data_switch_comparison(UINT8_T on_off);

/**
 * @berief: geta light bright data
 * @param [out] {OUT USHORT_T *Bright -> bright data return}
 * @return: OPERATE_RET
 */
OPERATE_RET app_light_ctrl_data_bright_get(USHORT_T *bright);

/**
 * @berief: get light temrperature data
 * @param [out] {OUT USHORT_T *Temperature -> temperature data return}
 * @return: OPERATE_RET
 */
OPERATE_RET app_light_ctrl_data_temper_get(USHORT_T *temperature);

/**
 * @berief: get light mode data
 * @param [out] {OUT UINT8_T *Mode -> mode data return}
 * @return: OPERATE_RET
 */
LIGHT_MODE_E app_light_ctrl_data_mode_get(VOID);

/**
 * @berief: set light countdown value
 * @param {IN INT_T CountDownSec -> unit:second}
 * @attention: countdown lave time will return with
 *              calling app_onoff_count_down_response function every minutes.
 *              switch status will return with calling
 *              light_ctrl_data_switch_response function when countdown active.
 * @return: OPERATE_RET -> OPRT_OK set countdown OK.
 */
OPERATE_RET app_onoff_data_count_down_set(ULONG_T count_down_cnt);

OPERATE_RET app_light_ctrl_data_ty_scene_set(UINT8_T *data, UINT8_T data_len);

UINT8_T *app_light_ctrl_data_ty_scene_get(VOID);

OPERATE_RET app_light_ctrl_data_power_memory_set(UINT8_T *data, UINT8_T data_len);

UINT8_T *app_light_ctrl_data_power_memory_get(VOID);

OPERATE_RET app_light_ctrl_data_do_not_disturb_set(UINT8_T no_disturb);

UINT8_T app_light_ctrl_data_do_not_disturb_get(VOID);

OPERATE_RET app_light_ctrl_data_switch_gradient_set(UINT8_T *data, UINT8_T data_len);

UINT8_T *app_light_ctrl_data_switch_gradient_get(VOID);

/**
 * @berief: Light hardware reboot judge & proc
 *          process detail:
 *                  1. load reboot cnt data;
 *                  2. reboot cnt data increase;
 *                  3. start software time to clear reboot cnt;
 * @param {none}
 * @return: none
 */
VOID_T dev_reset_cnt_proc(VOID_T);

/**
 * @berief: system reset proc
 * @param {none}
 * @attention: this function need implememt by system,
 *              need to deal with different thing in each plantform.
 * @return: none
 */
OPERATE_RET light_sys_reset_cnt_over_callback(VOID_T);

/**
 * @description: start blink
 * @param {IN ULONG_T BlinkTimeMs -> blink phase}
 * @attention: blink display will as the parm
 *             -- NetColor, usNetBright in configuration.
 * @return: none
 */
OPERATE_RET app_light_ctrl_blink_start(ULONG_T blink_time);

UINT8_T app_light_ctrl_nwk_flag_get(VOID);

/**
 * @description: stop blink
 * @param {type} none
 * @attention: blink stop will directly go to normal status display
 *              normal status will bright as default bright parm
 *              -- usDefBright,usDefTemper,DefColor in configuration.
 * @return: none
 */
OPERATE_RET app_light_ctrl_blink_stop(VOID_T);

OPERATE_RET app_light_ctrl_data_reset(VOID_T);

/**
 * @brief: 灯控制初始化接口
 * @param[in]: config_data 初始化的数据指针 
 * @attention: this function need apply tuya_light_sys_hardware_reboot_judge();
 * @return: OPERATE_LIGHT 0表示成功, 非0请参照tuya error code描述文档
 */
OPERATE_RET app_light_ctrl_init(void);

/**
 * @description: Move to off when shade stop
 * @param {type} bMoveToOff
 * @return:
 */
VOID_T app_light_ctrl_move_down_to_off_flag_set(VOID_T);

void app_light_ctrl_white_target_val(LIGHT_DATA_T *data);

SHADE_PARAM_E app_light_ctrl_shade_param_get(VOID);

/**
 * @description: Get shade remain time
 * @param [OUT]{RemainTime100ms} remain time: 100ms
 * @return: none
 */
VOID_T app_light_ctrl_remain_time_ms_get(USHORT_T *remain_time_100ms);

/**
 * @description: stop step level or move level
 * @param {type} none
 * @return: none
 */
OPERATE_RET app_light_ctrl_data_move_stop(VOID_T);

/**
 * @description: set level_move_down_to_off value
 * @param [in] {UINT8_T} flag
 * @return: none
 */
VOID_T app_light_ctrl_level_move_down_to_off_set(UINT8_T flag);

VOID_T app_light_ctrl_more_rst_set(VOID_T);

VOID_T app_light_ctrl_mf_blink_cb(TIMER_ID timer_id, VOID_T *arg);
VOID_T app_light_ctrl_power_on_sync_cb(TIMER_ID timer_id, VOID_T *arg);
VOID_T app_light_ctrl_join_end_sync_cb(TIMER_ID timer_id, VOID_T *arg);
VOID_T app_light_ctrl_save_data_delay_cb(TIMER_ID timer_id, VOID_T *arg);

#ifdef __cplusplus
}
#endif

#endif
